/**
 * ThemeSystem - 主题系统
 * 管理游戏的视觉主题，包括背景、颜色、音效等
 */

import { BackgroundManager, type ThemeConfig } from './BackgroundManager'

export interface ThemeAssets {
  /** 背景图片资源 */
  backgrounds: Map<string, HTMLImageElement>
  /** 音效资源 */
  sounds: Map<string, AudioBuffer>
  /** 音乐资源 */
  music: AudioBuffer | null
}

export interface ColorPalette {
  /** 主色调 */
  primary: string
  /** 次要色调 */
  secondary: string
  /** 强调色 */
  accent: string
  /** 文字颜色 */
  text: string
  /** 背景色 */
  background: string
  /** 危险色（障碍物等） */
  danger: string
  /** 成功色（道具等） */
  success: string
}

export interface ThemeData extends ThemeConfig {
  /** 颜色配置 */
  colors: ColorPalette
  /** 资源路径 */
  assets: {
    backgrounds: Record<string, string>
    sounds: Record<string, string>
    music?: string
  }
  /** 主题特效配置 */
  effects: {
    /** 粒子效果颜色 */
    particleColors: string[]
    /** 环境光效果 */
    ambientLight: {
      color: string
      intensity: number
    }
  }
}

export interface ThemeSystemOptions {
  /** Canvas宽度 */
  canvasWidth: number
  /** Canvas高度 */
  canvasHeight: number
  /** 资源基础路径 */
  assetsBasePath?: string
}

/**
 * 主题系统类
 * 统一管理游戏的视觉主题和相关资源
 */
export class ThemeSystem {
  private backgroundManager: BackgroundManager
  private themes: Map<string, ThemeData> = new Map()
  private currentTheme: string = ''
  private loadedAssets: Map<string, ThemeAssets> = new Map()
  private assetsBasePath: string
  private isLoading: boolean = false

  constructor(options: ThemeSystemOptions) {
    this.assetsBasePath = options.assetsBasePath || '/assets/themes'
    
    this.backgroundManager = new BackgroundManager({
      canvasWidth: options.canvasWidth,
      canvasHeight: options.canvasHeight
    })

    this.initializeDefaultThemes()
  }

  /**
   * 初始化默认主题数据
   */
  private initializeDefaultThemes(): void {
    // 城市主题
    this.addTheme({
      name: 'city',
      displayName: '城市跑酷',
      layers: [
        {
          name: 'sky',
          scrollSpeed: 50,
          parallaxLayer: 8,
          opacity: 1.0,
          repeat: true,
          width: 800,
          height: 400,
          y: 0
        },
        {
          name: 'buildings_far',
          scrollSpeed: 100,
          parallaxLayer: 6,
          opacity: 0.7,
          repeat: true,
          width: 1200,
          height: 240,
          y: 160
        },
        {
          name: 'buildings_near',
          scrollSpeed: 150,
          parallaxLayer: 3,
          opacity: 0.8,
          repeat: true,
          width: 960,
          height: 320,
          y: 80
        },
        {
          name: 'ground',
          scrollSpeed: 200,
          parallaxLayer: 1,
          opacity: 1.0,
          repeat: true,
          width: 800,
          height: 40,
          y: 360
        }
      ],
      colors: {
        primary: '#2196F3',
        secondary: '#607D8B',
        accent: '#FF9800',
        text: '#FFFFFF',
        background: '#87CEEB',
        danger: '#F44336',
        success: '#4CAF50'
      },
      assets: {
        backgrounds: {
          sky: 'city/sky.png',
          buildings_far: 'city/buildings_far.png',
          buildings_near: 'city/buildings_near.png',
          ground: 'city/ground.png'
        },
        sounds: {
          ambient: 'city/ambient.ogg',
          footstep: 'city/footstep.ogg'
        },
        music: 'city/theme.ogg'
      },
      effects: {
        particleColors: ['#87CEEB', '#2196F3', '#607D8B'],
        ambientLight: {
          color: '#87CEEB',
          intensity: 0.3
        }
      }
    })

    // 森林主题
    this.addTheme({
      name: 'forest',
      displayName: '森林探险',
      layers: [
        {
          name: 'sky',
          scrollSpeed: 30,
          parallaxLayer: 10,
          opacity: 1.0,
          repeat: true,
          width: 800,
          height: 400,
          y: 0
        },
        {
          name: 'mountains',
          scrollSpeed: 60,
          parallaxLayer: 8,
          opacity: 0.6,
          repeat: true,
          width: 1200,
          height: 160,
          y: 120
        },
        {
          name: 'trees_far',
          scrollSpeed: 100,
          parallaxLayer: 5,
          opacity: 0.7,
          repeat: true,
          width: 1040,
          height: 240,
          y: 160
        },
        {
          name: 'trees_near',
          scrollSpeed: 150,
          parallaxLayer: 2,
          opacity: 0.9,
          repeat: true,
          width: 880,
          height: 280,
          y: 120
        },
        {
          name: 'ground',
          scrollSpeed: 200,
          parallaxLayer: 1,
          opacity: 1.0,
          repeat: true,
          width: 800,
          height: 40,
          y: 360
        }
      ],
      colors: {
        primary: '#4CAF50',
        secondary: '#8BC34A',
        accent: '#FF5722',
        text: '#FFFFFF',
        background: '#87CEEB',
        danger: '#795548',
        success: '#CDDC39'
      },
      assets: {
        backgrounds: {
          sky: 'forest/sky.png',
          mountains: 'forest/mountains.png',
          trees_far: 'forest/trees_far.png',
          trees_near: 'forest/trees_near.png',
          ground: 'forest/ground.png'
        },
        sounds: {
          ambient: 'forest/birds.ogg',
          footstep: 'forest/leaves.ogg'
        },
        music: 'forest/theme.ogg'
      },
      effects: {
        particleColors: ['#4CAF50', '#8BC34A', '#CDDC39'],
        ambientLight: {
          color: '#90EE90',
          intensity: 0.2
        }
      }
    })

    // 沙漠主题
    this.addTheme({
      name: 'desert',
      displayName: '沙漠冒险',
      layers: [
        {
          name: 'sky',
          scrollSpeed: 40,
          parallaxLayer: 12,
          opacity: 1.0,
          repeat: true,
          width: 800,
          height: 400,
          y: 0
        },
        {
          name: 'dunes_far',
          scrollSpeed: 70,
          parallaxLayer: 7,
          opacity: 0.5,
          repeat: true,
          width: 1120,
          height: 120,
          y: 200
        },
        {
          name: 'dunes_near',
          scrollSpeed: 120,
          parallaxLayer: 3,
          opacity: 0.8,
          repeat: true,
          width: 960,
          height: 200,
          y: 200
        },
        {
          name: 'sand',
          scrollSpeed: 180,
          parallaxLayer: 1,
          opacity: 1.0,
          repeat: true,
          width: 800,
          height: 40,
          y: 360
        }
      ],
      colors: {
        primary: '#FF9800',
        secondary: '#FFC107',
        accent: '#E91E63',
        text: '#5D4037',
        background: '#FFE4B5',
        danger: '#8D6E63',
        success: '#FFEB3B'
      },
      assets: {
        backgrounds: {
          sky: 'desert/sky.png',
          dunes_far: 'desert/dunes_far.png',
          dunes_near: 'desert/dunes_near.png',
          sand: 'desert/sand.png'
        },
        sounds: {
          ambient: 'desert/wind.ogg',
          footstep: 'desert/sand.ogg'
        },
        music: 'desert/theme.ogg'
      },
      effects: {
        particleColors: ['#FFE4B5', '#FF9800', '#FFC107'],
        ambientLight: {
          color: '#FFE4B5',
          intensity: 0.4
        }
      }
    })
  }

  /**
   * 添加主题
   */
  addTheme(theme: ThemeData): void {
    this.themes.set(theme.name, theme)
    this.backgroundManager.addTheme(theme)
  }

  /**
   * 设置当前主题
   */
  async setTheme(themeName: string): Promise<void> {
    const theme = this.themes.get(themeName)
    if (!theme) {
      throw new Error(`Theme "${themeName}" not found`)
    }

    // 加载主题资源
    await this.loadThemeAssets(theme)
    
    // 设置背景管理器的主题
    this.backgroundManager.setTheme(themeName)
    
    this.currentTheme = themeName
  }

  /**
   * 平滑切换主题
   */
  async switchTheme(themeName: string, duration: number = 2000): Promise<void> {
    const theme = this.themes.get(themeName)
    if (!theme) {
      throw new Error(`Theme "${themeName}" not found`)
    }

    // 预加载新主题资源
    await this.loadThemeAssets(theme)
    
    // 执行背景切换
    await this.backgroundManager.switchTheme(themeName, duration)
    
    this.currentTheme = themeName
  }

  /**
   * 加载主题资源
   */
  private async loadThemeAssets(theme: ThemeData): Promise<void> {
    if (this.loadedAssets.has(theme.name)) {
      return // 已加载
    }

    this.isLoading = true

    try {
      const assets: ThemeAssets = {
        backgrounds: new Map(),
        sounds: new Map(),
        music: null
      }

      // 加载背景图片
      const backgroundPromises = Object.entries(theme.assets.backgrounds).map(
        async ([name, path]) => {
          try {
            const image = await this.loadImage(`${this.assetsBasePath}/${path}`)
            assets.backgrounds.set(name, image)
          } catch (error) {
            console.warn(`Failed to load background image: ${path}`, error)
          }
        }
      )

      // 加载音效
      const soundPromises = Object.entries(theme.assets.sounds).map(
        async ([name, path]) => {
          try {
            const buffer = await this.loadAudio(`${this.assetsBasePath}/${path}`)
            assets.sounds.set(name, buffer)
          } catch (error) {
            console.warn(`Failed to load sound: ${path}`, error)
          }
        }
      )

      // 加载背景音乐
      let musicPromise: Promise<void> = Promise.resolve()
      if (theme.assets.music) {
        musicPromise = this.loadAudio(`${this.assetsBasePath}/${theme.assets.music}`)
          .then(buffer => {
            assets.music = buffer
          })
          .catch(error => {
            console.warn(`Failed to load music: ${theme.assets.music}`, error)
          })
      }

      // 等待所有资源加载完成
      await Promise.all([...backgroundPromises, ...soundPromises, musicPromise])

      this.loadedAssets.set(theme.name, assets)
    } finally {
      this.isLoading = false
    }
  }

  /**
   * 加载图片资源
   */
  private loadImage(src: string): Promise<HTMLImageElement> {
    return new Promise((resolve, reject) => {
      const img = new Image()
      img.onload = () => resolve(img)
      img.onerror = reject
      img.src = src
    })
  }

  /**
   * 加载音频资源
   */
  private loadAudio(src: string): Promise<AudioBuffer> {
    return new Promise((resolve, reject) => {
      fetch(src)
        .then(response => response.arrayBuffer())
        .then(data => {
          const audioContext = new (window.AudioContext || (window as any).webkitAudioContext)()
          return audioContext.decodeAudioData(data)
        })
        .then(resolve)
        .catch(reject)
    })
  }

  /**
   * 获取当前主题数据
   */
  getCurrentThemeData(): ThemeData | null {
    return this.currentTheme ? this.themes.get(this.currentTheme) || null : null
  }

  /**
   * 获取当前主题的颜色配置
   */
  getCurrentColors(): ColorPalette | null {
    const theme = this.getCurrentThemeData()
    return theme ? theme.colors : null
  }

  /**
   * 获取当前主题的资源
   */
  getCurrentAssets(): ThemeAssets | null {
    return this.currentTheme ? this.loadedAssets.get(this.currentTheme) || null : null
  }

  /**
   * 获取所有可用主题
   */
  getAvailableThemes(): ThemeData[] {
    return Array.from(this.themes.values())
  }

  /**
   * 检查主题是否已加载
   */
  isThemeLoaded(themeName: string): boolean {
    return this.loadedAssets.has(themeName)
  }

  /**
   * 检查是否正在加载
   */
  isLoadingAssets(): boolean {
    return this.isLoading
  }

  /**
   * 更新背景系统
   */
  update(deltaTime: number): void {
    this.backgroundManager.update(deltaTime)
  }

  /**
   * 渲染背景
   */
  render(ctx: CanvasRenderingContext2D): void {
    this.backgroundManager.render(ctx)
  }

  /**
   * 设置全局滚动速度
   */
  setScrollSpeed(speed: number): void {
    this.backgroundManager.setGlobalScrollSpeed(speed)
  }

  /**
   * 重置背景位置
   */
  reset(): void {
    this.backgroundManager.reset()
  }

  /**
   * 获取背景管理器
   */
  getBackgroundManager(): BackgroundManager {
    return this.backgroundManager
  }

  /**
   * 清理资源
   */
  cleanup(): void {
    this.backgroundManager.cleanup()
    this.loadedAssets.clear()
    this.themes.clear()
  }
}